#include "StdAfx.h"
#include <string>
#include <Util/StringUtil.h>
#include <interface/data_op/table_wrapper.h>
#include "sms_op.h"

namespace aot{ namespace data{

sms_op_impl::sms_op_impl(void)
{
}

sms_op_impl::~sms_op_impl(void)
{
}

bool 
sms_op_impl::insert(const isms_info* p, int* new_id)
{
    if (!g_db_user) return false;

    std::string str_from_or_to = p->from_or_to->c_str();
    std::string str_from_or_to_nickname = p->from_or_to_nickname->c_str();
    std::string str_content = p->content->c_str();
    std::string str_send_datetime = p->send_datetime->c_str();
    std::string str_send_short_time = p->send_short_time->c_str();

    remove_sin_quot(str_from_or_to);
    remove_sin_quot(str_from_or_to_nickname);
    remove_sin_quot(str_content);
    remove_sin_quot(str_send_datetime);
    remove_sin_quot(str_send_short_time);

    std::string sql_fmt = 
        "insert into sms \
        (id,\
        group_id,\
        read_flag,\
        send_channel,\
        is_from_me,\
        result, \
        from_or_to,\
        from_or_to_nickname,\
        content,\
        send_datetime,\
        send_short_time) \
        values\
        (%d, %d, %d, %d, %d, %d, '%s', '%s', '%s', '%s' , '%s')";

    std::string sql_exe;
    int t_new_id = get_table_next_id("sms");

    sql_exe = aot::tt::utility::StrUtil::Printf(sql_fmt.c_str(),
        t_new_id,
        p->group_id,
        p->read_flag,
        p->send_channel,
        p->is_from_me,
        p->result,
        str_from_or_to.c_str(),
        str_from_or_to_nickname.c_str(),
        str_content.c_str(),
        str_send_datetime.c_str(),
        str_send_short_time.c_str()
        );

    *new_id = t_new_id;
    return g_db_user->exec(sql_exe.c_str());
}

bool 
sms_op_impl::del(int id)
{
    std::string sql_fmt = "delete from sms where id=%d";
    std::string sql_exe = aot::tt::utility::StrUtil::Printf(sql_fmt.c_str(), id);
    return g_db_user->exec(sql_exe.c_str());
}


bool 
sms_op_impl::update(const isms_info* p)
{
    if (!g_db_user) return false;

    std::string str_from_or_to = p->from_or_to->c_str();
    std::string str_from_or_to_nickname = p->from_or_to_nickname->c_str();
    std::string str_content = p->content->c_str();
    std::string str_send_datetime = p->send_datetime->c_str();
    std::string str_send_short_time = p->send_short_time->c_str();

    remove_sin_quot(str_from_or_to);
    remove_sin_quot(str_from_or_to_nickname);
    remove_sin_quot(str_content);
    remove_sin_quot(str_send_datetime);
    remove_sin_quot(str_send_short_time);

    std::string sql_fmt = 
        "update sms set \
        group_id=%d,\
        read_flag=%d,\
        send_channel=%d,\
        is_from_me=%d,\
        result=%d, \
        from_or_to='%s',\
        from_or_to_nickname='%s',\
        content='%s',\
        send_datetime='%s', \
        send_short_time='%s' \
        where id=%d";

    std::string sql_exe;
    sql_exe = aot::tt::utility::StrUtil::Printf(sql_fmt.c_str(),
        p->group_id,
        p->read_flag,
        p->send_channel,
        p->is_from_me,
        p->result,
        str_from_or_to.c_str(),
        str_from_or_to_nickname.c_str(),
        str_content.c_str(),
        str_send_datetime.c_str(),
        str_send_short_time.c_str(),
        p->id
        );

    return g_db_user->exec(sql_exe.c_str());
}

bool 
sms_op_impl::read(int id, isqlite3_table** out)
{
    std::string sql_fmt = "select \
                            id,\
                            group_id,\
                            read_flag,\
                            send_channel,\
                            is_from_me,\
                            result, \
                            from_or_to,\
                            from_or_to_nickname,\
                            content,\
                            send_datetime, \
                            send_short_time \
                            from sms \
                            where id=%d";
    std::string sql_exe = aot::tt::utility::StrUtil::Printf(sql_fmt.c_str(), id);
    return g_db_user->exec_and_get_record(sql_exe.c_str(), out);
}

bool 
sms_op_impl::read(int id, isms_info* out)
{
    aot::data::table_helper t_table;
    bool bRet =false;
    if ( this->read(id, t_table) )
    {
        if ( t_table.get_rows_count() > 0 )
        {
            t_table.set_row_index(0);

            out->id = t_table.get_field_value_int("id");
            out->group_id = t_table.get_field_value_int("group_id");
            out->read_flag = t_table.get_field_value_int("read_flag");
            out->send_channel = t_table.get_field_value_int("send_channel");
            out->is_from_me = t_table.get_field_value_int("is_from_me");
            out->result = t_table.get_field_value_int("result");
          

            out->from_or_to->assign(t_table.get_field_value_str("from_or_to").c_str());
            out->from_or_to_nickname->assign(t_table.get_field_value_str("from_or_to_nickname").c_str());
            out->content->assign(t_table.get_field_value_str("content").c_str());
            out->send_datetime->assign(t_table.get_field_value_str("send_datetime").c_str());
            out->send_short_time->assign(t_table.get_field_value_str("send_short_time").c_str());

            bRet = true;
        }


    }
    return bRet;
}

bool 
sms_op_impl::read(int id, isms_info** out)
{
    aot::data::isms_info* obj = new aot::data::sms_info_impl();
    *out = obj;
    return this->read(id, obj);
}

bool 
sms_op_impl::get_sms_list_by_group_id(int group_id, isqlite3_table** out)
{
    std::string sql_fmt = "select \
                            id,\
                            group_id,\
                            read_flag,\
                            send_channel,\
                            is_from_me,\
                            result, \
                            from_or_to,\
                            from_or_to_nickname,\
                            content,\
                            send_datetime, \
                            send_short_time \
                            from sms \
                            where group_id=%d";
    std::string sql_exe = aot::tt::utility::StrUtil::Printf(sql_fmt.c_str(), group_id);
    return g_db_user->exec_and_get_record(sql_exe.c_str(), out);
}

bool 
sms_op_impl::get_sms_list_by_group_id_and_read_flag(int group_id, int read_flag, isqlite3_table** out)
{
    std::string sql_fmt = "select \
                            id,\
                            group_id,\
                            read_flag,\
                            send_channel,\
                            is_from_me,\
                            result, \
                            from_or_to,\
                            from_or_to_nickname,\
                            content,\
                            send_datetime, \
                            send_short_time \
                            from sms \
                            where group_id=%d and read_flag=%d";
    std::string sql_exe = aot::tt::utility::StrUtil::Printf(sql_fmt.c_str(), group_id, read_flag);
    return g_db_user->exec_and_get_record(sql_exe.c_str(), out);
}

bool 
sms_op_impl::get_sms_list_by_sender(const char* sender, isqlite3_table** out)
{
    std::string sql_fmt = "select \
                          id,\
                          group_id,\
                          read_flag,\
                          send_channel,\
                          is_from_me,\
                          result, \
                          from_or_to,\
                          from_or_to_nickname,\
                          content,\
                          send_datetime, \
                          send_short_time \
                          from sms \
                          where from_or_to='%s';";
    std::string sql_exe = aot::tt::utility::StrUtil::Printf(sql_fmt.c_str(), sender);
    return g_db_user->exec_and_get_record(sql_exe.c_str(), out);
}

int 
sms_op_impl::get_count_by_group_id(int group_id)
{
    int total;
    std::string sql_fmt = "select count(*) as t from sms where group_id=%d;";
    std::string sql_exe = aot::tt::utility::StrUtil::Printf(sql_fmt.c_str(), group_id);
    if ( 0 == group_id )
    {
        sql_exe = "select count(*) as t from sms;";
    }
    total = g_db_user->exec_scalar(sql_exe.c_str());
    return total;
}

bool 
sms_op_impl::get_page_records_by_group_id(int group_id, int count_per_page, int page_index, isqlite3_table** out)
{
    int total = get_count_by_group_id(group_id);

    int limit;
    int offset;

    this->cal_page_info(total, count_per_page, page_index, limit, offset);

    std::string sql_fmt;
    std::string sql_exe;

    if ( 0 != group_id )
    {
        sql_fmt = "select \
                  id,\
                  group_id,\
                  read_flag,\
                  send_channel,\
                  is_from_me,\
                  result, \
                  from_or_to,\
                  from_or_to_nickname,\
                  content,\
                  send_datetime, \
                  send_short_time \
                  from sms \
                  where group_id=%d order by send_datetime limit %d offset %d;";
        sql_exe = aot::tt::utility::StrUtil::Printf(sql_fmt.c_str(), group_id, limit, offset);
    }
    else
    {
        sql_fmt = "select \
                  id,\
                  group_id,\
                  read_flag,\
                  send_channel,\
                  is_from_me,\
                  result, \
                  from_or_to,\
                  from_or_to_nickname,\
                  content,\
                  send_datetime, \
                  send_short_time \
                  from sms \
                  order by send_datetime limit %d offset %d;";
        sql_exe = aot::tt::utility::StrUtil::Printf(sql_fmt.c_str(), limit, offset);
    }
    


    return g_db_user->exec_and_get_record(sql_exe.c_str(), out);
}

int 
sms_op_impl::get_count_by_keyword(int group_id, const char* keyword)
{
    int total;
    std::string sql_fmt;
    std::string str_keyword;
    std::string sql_exe;

    str_keyword = keyword;
    remove_sin_quot(str_keyword);
    str_keyword = "%" + str_keyword + "%";

    if ( 0 != group_id )
    {
        sql_fmt = "select count(*) as t from sms where group_id=%d and content like '%s';";
        sql_exe = aot::tt::utility::StrUtil::Printf(sql_fmt.c_str(), group_id, str_keyword.c_str());
    }
    else
    {
        sql_fmt = "select count(*) as t from sms where content like '%s';";
        sql_exe = aot::tt::utility::StrUtil::Printf(sql_fmt.c_str(), str_keyword.c_str());
    }
    
    total = g_db_user->exec_scalar(sql_exe.c_str());
    return total;
}

bool 
sms_op_impl::get_page_records_by_keyword(int group_id, const char* keyword, int count_per_page, int page_index, isqlite3_table** out)
{
    int total = get_count_by_keyword(group_id, keyword);

    int limit;
    int offset;

    this->cal_page_info(total, count_per_page, page_index, limit, offset);

    std::string sql_fmt;
    std::string str_keyword;
    std::string sql_exe;

    str_keyword = keyword;
    remove_sin_quot(str_keyword);
    str_keyword = "%" + str_keyword + "%";

    if ( 0 != group_id )
    {
        sql_fmt = "select \
                  id,\
                  group_id,\
                  read_flag,\
                  send_channel,\
                  is_from_me,\
                  result, \
                  from_or_to,\
                  from_or_to_nickname,\
                  content,\
                  send_datetime, \
                  send_short_time \
                  from sms \
                  where group_id=%d  and content like '%s' order by send_datetime limit %d offset %d;";

        sql_exe = aot::tt::utility::StrUtil::Printf(sql_fmt.c_str(), group_id, str_keyword.c_str(), limit, offset);
    }
    else
    {
        sql_fmt = "select \
                  id,\
                  group_id,\
                  read_flag,\
                  send_channel,\
                  is_from_me,\
                  result, \
                  from_or_to,\
                  from_or_to_nickname,\
                  content,\
                  send_datetime, \
                  send_short_time \
                  from sms \
                  where content like '%s' order by send_datetime limit %d offset %d;";

        sql_exe = aot::tt::utility::StrUtil::Printf(sql_fmt.c_str(), str_keyword.c_str(), limit, offset);
    }
    
    return g_db_user->exec_and_get_record(sql_exe.c_str(), out);
}


bool 
sms_op_impl::add_group(const isms_group_info* p, int& new_id)
{
    if (!g_db_user) return false;

    std::string str_group_name = p->group_name->c_str();	
    remove_sin_quot(str_group_name);

    std::string sql_fmt = 
        "insert into sms_group \
        (id,\
        parent_group_id,\
        group_name) \
        values\
        (%d, %d, '%s');";

    std::string sql_exe;
    //int t_new_id = get_table_next_id("sms_group");

    sql_exe = aot::tt::utility::StrUtil::Printf(sql_fmt.c_str(),
        p->id,
        p->parent_group_id,
        str_group_name.c_str()
        );

    new_id = p->id;
    return g_db_user->exec(sql_exe.c_str());
}

bool 
sms_op_impl::del_group(int id)
{
    std::string sql_fmt = "delete from sms_group where parent_group_id=%d;delete from sms_group where id=%d;";
    std::string sql_exe = aot::tt::utility::StrUtil::Printf(sql_fmt.c_str(), id, id);
    return g_db_user->exec(sql_exe.c_str());
}

bool 
sms_op_impl::del_by_group_id(int group_id)
{
	std::string sql_fmt = "delete from sms where group_id=%d;";
	std::string sql_exe = aot::tt::utility::StrUtil::Printf(sql_fmt.c_str(), group_id);
	return g_db_user->exec(sql_exe.c_str());
}
bool 
sms_op_impl::update_group(const isms_group_info* p)
{
    if (!g_db_user) return false;
   
    std::string str_group_name = p->group_name->c_str();	
    remove_sin_quot(str_group_name);

    std::string sql_fmt = 
        "update sms_group set \
        parent_group_id=%d,\
        group_name='%s' \
        where id=%d;";

    std::string sql_exe;

    sql_exe = aot::tt::utility::StrUtil::Printf(sql_fmt.c_str(),
        p->parent_group_id,
        str_group_name.c_str(),
        p->id
        );
    return g_db_user->exec(sql_exe.c_str());
}

bool 
sms_op_impl::get_group(int id, isqlite3_table** out)
{
    std::string sql_fmt =   "select \
                            id,parent_group_id,group_name \
                            from sms_group \
                            where id=%d";
    std::string sql_exe = aot::tt::utility::StrUtil::Printf(sql_fmt.c_str(), id);
    return g_db_user->exec_and_get_record(sql_exe.c_str(), out);
}

bool 
sms_op_impl::get_group(int id, isms_group_info* out)
{
    aot::data::table_helper t_table;
    bool ret =false;
    if ( this->read(id, t_table) )
    {
        if ( t_table.get_rows_count() > 0 )
        {
            t_table.set_row_index(0);

            out->id = t_table.get_field_value_int("id");
            out->parent_group_id = t_table.get_field_value_int("parent_group_id");
            out->group_name->assign(t_table.get_field_value_str("group_name").c_str());
            ret = true;
        }
    }
    return ret;
}

bool 
sms_op_impl::get_group(int id, isms_group_info** out)
{
    aot::data::isms_group_info* obj = new aot::data::sms_group_info_impl();
    *out = obj;
    return this->get_group(id, obj);
}

bool sms_op_impl::get_groups( isqlite3_table** out )
{
	std::string sql_fmt =   "select \
							id,parent_group_id,group_name \
							from sms_group;";
	return g_db_user->exec_and_get_record(sql_fmt.c_str(), out);
}
bool 
sms_op_impl::is_root_group(int id)
{
    aot::tt::iobj_auto_ptr<aot::data::isms_group_info> group_info;
    this->get_group(id, group_info);

    return ( 0 == group_info->parent_group_id );
}

bool 
sms_op_impl::get_sub_group(int parent_id,  isqlite3_table** out)
{
    std::string sql_fmt = "select \
                            id,parent_group_id,group_name \
                            from sms_group \
                            where parent_group_id=%d";
    std::string sql_exe = aot::tt::utility::StrUtil::Printf(sql_fmt.c_str(), parent_id);
    return g_db_user->exec_and_get_record(sql_exe.c_str(), out);    
}

}} /* end namespace aot/data*/

bool 
aot::data::sms_op_impl::move_to_group( int id, int group_id )
{
	if (!g_db_user) return false;

	std::string sql_fmt = "update sms set	group_id=%d where id=%d;";

	std::string sql_exe;
	sql_exe = aot::tt::utility::StrUtil::Printf(sql_fmt.c_str(),
		group_id,
		id
		);
	return g_db_user->exec(sql_exe.c_str());
}

bool 
aot::data::sms_op_impl::is_group_exist( int group_id )
{
	std::string sql_fmt = "select \
						  id,parent_group_id,group_name \
						  from sms_group \
						  where id=%d";
	std::string sql_exe = aot::tt::utility::StrUtil::Printf(sql_fmt.c_str(), group_id);
	aot::data::table_helper t_table;

	if ( g_db_user->exec_and_get_record(sql_exe.c_str(), t_table) )
	{
		if ( t_table.get_rows_count() > 0)
			return true;
		else
			return false;
	}
	return false;
	
}

int 
aot::data::sms_op_impl::get_group_count()
{
	return g_db_user->exec_scalar( "select count(*) as t from  sms_group");
}

bool 
aot::data::sms_op_impl::update_read_flag( int id, int old_flag, int new_flag )
{
	std::string sql_fmt = 
		"update sms set \
		read_flag=%d,\
		where id=%d and read_flag=%d;";

	std::string sql_exe;

	sql_exe = aot::tt::utility::StrUtil::Printf(sql_fmt.c_str(),
		new_flag,
		id,
		old_flag
		);
	return g_db_user->exec(sql_exe.c_str());
}

int 
aot::data::sms_op_impl::get_count_by_read_flg( int flag )
{
	std::string sql_fmt = "select count(*) as t from sms where read_flag=%d;";
	std::string	sql_exe = aot::tt::utility::StrUtil::Printf(sql_fmt.c_str(), flag);
	return g_db_user->exec_scalar(sql_exe.c_str());
}